//package com.ls.utils.pay;
//
//
////import com.luo.expression.bean.entity.order.OrderPrepare;
////import com.luo.expression.bean.entity.order.OrderUser;
////import com.luo.expression.data.GlobalConstant;
////import com.luo.expression.utils.Md5Utils;
////import com.luo.expression.utils.TimeUtils;
////import com.luo.expression.utils.TxtUtil;
//import com.wechat.pay.java.core.Config;
//import com.wechat.pay.java.core.RSAAutoCertificateConfig;
//import com.wechat.pay.java.core.exception.ServiceException;
//import com.wechat.pay.java.service.payments.model.Transaction;
//import com.wechat.pay.java.service.payments.nativepay.NativePayService;
//import com.wechat.pay.java.service.payments.nativepay.model.Amount;
//import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
//import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
//import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByOutTradeNoRequest;
//import com.wechat.pay.java.service.transferbatch.TransferBatchService;
//import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
//import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
//import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
//
//import org.apache.http.conn.ssl.NoopHostnameVerifier;
//import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.apache.http.impl.client.HttpClients;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.http.HttpEntity;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
//import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
//import org.springframework.stereotype.Component;
//import org.springframework.util.LinkedMultiValueMap;
//import org.springframework.util.MultiValueMap;
//import org.springframework.web.client.RestTemplate;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.math.BigDecimal;
//import java.security.KeyStore;
//import java.util.ArrayList;
//import java.util.Calendar;
//import java.util.Collections;
//import java.util.Comparator;
//import java.util.List;
//import java.util.Map;
//import java.util.TreeMap;
//import java.util.UUID;
//
//import javax.net.ssl.KeyManagerFactory;
//import javax.net.ssl.SSLContext;
//
//import cn.hutool.core.lang.Snowflake;
//
//@Component
//public class WeChatPayUtils {
//    //    /**
////     * 商户的key(后台设置的key)
////     */
//    public static String APIKEY = "xianshengduorenluo88888888888888";
//    public static String MP_APPID = GlobalConstant.getWX_APPID(3);
//    public static String MP_APPSECERT = GlobalConstant.getWX_SECERT(3);
//    public static String APP_APPID = GlobalConstant.getAPPWX_APPID(3);
//    public static String APP_APPSECERT = GlobalConstant.getAPPWX_SECERT(3);
//
//    @Value("${wechatPrivateKeyPath}")
//    String wechatPrivateKeyPath;
//    @Autowired
//    Snowflake snowflake;
//
//
//    /**
//     * 预支付方法
//     *
//     * @param title       订单标题
//     * @param detail      订单描述详情
//     * @param orderNum    平台的订单号
//     * @param total_fee   总价单位为分，所以以元为单位的价格需要乘以100，不能带小数
//     * @param openid      登录时的开放平台id，可以查询用户登录信息得到
//     * @param payPlatform 支付平台和用户平台枚举统一
//     */
//    public static WechatPrepareReturn preparePay(RestTemplate restTemplate, String title,
//                                                 String detail, String orderNum, Integer total_fee,
//                                                 String openid, Integer payPlatform, Integer appOrigin) {
//        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
//        if (payPlatform == 4) {
//            map.add("appid", GlobalConstant.getWX_APPID(appOrigin));//MP_APPID
//        } else if (payPlatform == 1) {
//            map.add("appid", GlobalConstant.getAPPWX_APPID(appOrigin));//APP_APPID
//        }
//        map.add("mch_id", GlobalConstant.SHANGHUHAO);//商户号
//        if (payPlatform == 4) {
//            map.add("device_info", "xiaochengxu");//设备号
//        } else if (payPlatform == 1) {
//            map.add("device_info", "app");//设备号
//        }
//
//        map.add("nonce_str", UUID.randomUUID().toString().replace("-", ""));//随机字符串，长度要求在32位以内。
//        map.add("sign_type", "MD5");//签名类型，默认为MD5，支持HMAC-SHA256和MD5。
//        map.add("body", title);//商品简单描述，该字段请按照规范传递，具体请见参数规定
//        map.add("detail", detail);//商品简单描述，该字段请按照规范传递，具体请见参数规定
////        map.add("attach", "");//附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
//        map.add("out_trade_no", orderNum);//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
//        if (payPlatform == 4)
//            map.add("fee_type", "CNY");//符合ISO 4217标准的三位字母代码，默认人民币：CNY，详细列表请参见货币类型
//        map.add("total_fee", total_fee);//订单总金额，单位为分，详见支付金额
//        map.add("spbill_create_ip", "127.0.0.1");//支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
//        map.add("time_start", TimeUtils.getLocalDate("yyyyMMddHHmmss"));//订单生成时间，格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
//        Calendar calendar = Calendar.getInstance();
//        calendar.add(Calendar.HOUR_OF_DAY, 2);
//        map.add("time_expire", TimeUtils.getTimeStringByTimetamp(calendar.getTimeInMillis(), "yyyyMMddHHmmss"));//订单失效时间，格式为yyyyMMddHHmmss，如2009年12月27日9点10分10秒表示为20091227091010。订单失效时间是针对订单号而言的，由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期，所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。其他详见时间规则
////        map.add("goods_tag", "");//订单优惠标记，使用代金券或立减优惠功能时需要的参数，说明详见代金券或立减优惠
//        if (payPlatform == 4) {
//            map.add("trade_type", "JSAPI");//小程序取值如下：JSAPI，详细说明见参数规定
//        } else if (payPlatform == 1) {
//            map.add("trade_type", "APP");//小程序取值如下：JSAPI，详细说明见参数规定
//        }
//
////        map.add("product_id", "");//trade_type=NATIVE时，此参数必传。此参数为二维码中包含的商品ID，商户自行定义。
////        map.add("limit_pay", "");//上传此参数no_credit--可限制用户不能使用信用卡支付
//        if (payPlatform == 4)
//            map.add("openid", openid);//trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识。openid如何获取，可参考【获取openid】。
////        map.add("receipt", "");//Y，传入Y时，支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能，传此字段才可生效
////        map.add("scene_info", "");//该字段常用于线下活动时的场景信息上报，支持上报实际门店信息，商户也可以按需求自己上报相关信息。该字段为JSON对象数据，对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }} ，字段详细说明请点击行前的+展开
//        map.add("notify_url", "https://expression.xsdr.top/expression/api/shop/order/paySuccessCallback?md5=&orderNum=" + orderNum);//异步接收微信支付退款结果通知的回调地址，通知URL必须为外网可访问的url，不允许带参数如果参数中传了notify_url，则商户平台上配置的回调地址将不会生效。
////        map.add("sign", getSign(map));//通过签名算法计算得出的签名值，详见签名生成算法,本行务必放在最后
//
//        HttpHeaders headers = new HttpHeaders();
////        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//        headers.setContentType(MediaType.APPLICATION_XML);
//
//
//        //排序参数
//        TreeMap<String, String> treeMap = new TreeMap<>();
//        //把map转换成treemap成有序映射
//        for (int i = 0; i < map.size(); i++) {
//            String key = map.keySet().toArray()[i] + "";
//            if ("sign".equals(key)) {
//                continue;
//            }
//            treeMap.put(key, map.values().toArray()[i] + "");
//            System.out.println(key + "   :   " + map.values().toArray()[i]);
//        }
//
//        List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(treeMap.entrySet());
//        //然后通过比较器来实现排序
//        Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
//            //升序排序
//            public int compare(Map.Entry<String, String> o1,
//                               Map.Entry<String, String> o2) {
//                return o1.getKey().compareTo(o2.getKey());
//            }
//        });
//
//        StringBuffer xmlString = new StringBuffer();
//        xmlString.append("<xml>");
//        for (int i = 0; i < treeMap.size(); i++) {
//            String key = treeMap.keySet().toArray()[i].toString();
//            String value = treeMap.values().toArray()[i].toString();
//
//            if ("sign".equals(key))
//                continue;
//
//            xmlString.append("<" + key + ">");
//            xmlString.append("<![CDATA");//CDATA标签用于说明数据不被XML解析器解析。
//            xmlString.append(value);
//            xmlString.append("]>");
//
//            xmlString.append("</" + key + ">");
//        }
//        //前面默认放在最后
//        xmlString.append("<sign>");
//        xmlString.append(getPrepareSign(map, APIKEY));
//        xmlString.append("</sign>");
//
//        xmlString.append("</xml>");
//
////        String str = xmlString.toString().replace("[", "").replace("]", "");
//        String str = xmlString.toString();
////         创建 HttpEntity
//        HttpEntity<String> requestEntity = new HttpEntity<>(xmlString.toString()
//                , headers);
//
//        String result = restTemplate.postForObject(url, requestEntity, String.class);
//
//        WechatPrepareReturn orderWechatPrepare = (WechatPrepareReturn) XmlUtils.convertXmlStrToObject(result, WechatPrepareReturn.class);
//        WechatPrepareReturn orderWechatPrepare2 = (WechatPrepareReturn) XmlUtils.convertXmlStrToObject(xmlString.toString(), WechatPrepareReturn.class);
//
//        //补充完整基本参数
//        if (!"FAIL".equals(orderWechatPrepare.getResult_code())) {
//            orderWechatPrepare2.setPrepay_id(orderWechatPrepare.getPrepay_id());
//        }
//        orderWechatPrepare2.setReturn_code(orderWechatPrepare.getReturn_code());
//        orderWechatPrepare2.setReturn_msg(orderWechatPrepare.getReturn_msg());
//        orderWechatPrepare2.setResult_code(orderWechatPrepare.getResult_code());
//        orderWechatPrepare2.setErr_code_des(orderWechatPrepare.getErr_code_des());
//        orderWechatPrepare2.setRequestXml(xmlString.toString());
//        orderWechatPrepare2.setRequestXml(xmlString.toString());
//        orderWechatPrepare2.setReturnXml(result);
//
//        return orderWechatPrepare2;
//    }
//
//    /**
//     * 查询订单是否已经支付
//     *
//     * @param orderNum 平台的订单号
//     */
//    public static WechatOrderReturn isPayOrder(RestTemplate restTemplate, String orderNum, Integer payPlatform) {
//        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
//        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
//        if (payPlatform == 4) {
//            map.add("appid", MP_APPID);//MP_APPID
//        } else if (payPlatform == 1) {
//            map.add("appid", APP_APPID);//APP_APPID
//        }
//        map.add("mch_id", GlobalConstant.SHANGHUHAO);//商户号
//        map.add("nonce_str", UUID.randomUUID().toString().replace("-", ""));//随机字符串，长度要求在32位以内。
//        map.add("sign_type", "MD5");//签名类型，默认为MD5，支持HMAC-SHA256和MD5。
//        map.add("out_trade_no", orderNum);//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
////        map.add("sign", getSign(map));//通过签名算法计算得出的签名值，详见签名生成算法,本行务必放在最后
//
//        HttpHeaders headers = new HttpHeaders();
////        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//        headers.setContentType(MediaType.APPLICATION_XML);
//
//        //排序参数
//        TreeMap<String, String> treeMap = new TreeMap<>();
//        //把map转换成treemap成有序映射
//        for (int i = 0; i < map.size(); i++) {
//            String key = map.keySet().toArray()[i] + "";
//            if ("sign".equals(key)) {
//                continue;
//            }
//            treeMap.put(key, map.values().toArray()[i] + "");
//        }
//        List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(treeMap.entrySet());
//        //然后通过比较器来实现排序
//        Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
//            //升序排序
//            public int compare(Map.Entry<String, String> o1,
//                               Map.Entry<String, String> o2) {
//                return o1.getKey().compareTo(o2.getKey());
//            }
//        });
//
//        StringBuffer xmlString = new StringBuffer();
//        xmlString.append("<xml>");
//        for (int i = 0; i < treeMap.size(); i++) {
//            String key = treeMap.keySet().toArray()[i].toString();
//            String value = treeMap.values().toArray()[i].toString();
//
//            if ("sign".equals(key))
//                continue;
//
//            xmlString.append("<" + key + ">");
//            xmlString.append("<![CDATA");//CDATA标签用于说明数据不被XML解析器解析。
//            xmlString.append(value);
//            xmlString.append("]>");
//
//            xmlString.append("</" + key + ">");
//        }
//        //前面默认放在最后
//        xmlString.append("<sign>");
//        xmlString.append(getPrepareSign(map, APIKEY));
//        xmlString.append("</sign>");
//
//        xmlString.append("</xml>");
//
////        String str = xmlString.toString().replace("[", "").replace("]", "");
//        // 创建 HttpEntity
//        HttpEntity<String> requestEntity = new HttpEntity<>(xmlString.toString()
//                , headers);
//
//        String result = restTemplate.postForObject(url, requestEntity, String.class);
//
//        WechatOrderReturn wechatOrderReturn = (WechatOrderReturn) XmlUtils.convertXmlStrToObject(result, WechatOrderReturn.class);
//
//        return wechatOrderReturn;
//    }
//
//    /**
//     * 申请退款订单
//     *
//     * @param certFilePath p12的证书文件通常文件名为 apiclient_cert.p12
//     */
//    public static WechatOrderReturn refundOrder(RestTemplate restTemplate, String certFilePath, String orderNum, String refundNum
//            , Integer total_fee, Integer refund_fee, String refund_desc, Integer payPlatform) {
//        String url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
//        if (payPlatform == 4) {
//            map.add("appid", MP_APPID);//MP_APPID
//        } else if (payPlatform == 1) {
//            map.add("appid", APP_APPID);//APP_APPID
//        }
//        map.add("mch_id", GlobalConstant.SHANGHUHAO);//商户号
//        map.add("nonce_str", UUID.randomUUID().toString().replace("-", ""));//随机字符串，长度要求在32位以内。
//        map.add("sign_type", "MD5");//签名类型，默认为MD5，支持HMAC-SHA256和MD5。
//        map.add("out_trade_no", orderNum);//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
//        map.add("out_refund_no", refundNum);//商户系统内部退款号
//        map.add("total_fee", total_fee);//订单总金额，单位为分，详见支付金额
//        map.add("refund_fee", refund_fee);////退款金额
//        map.add("refund_fee_type", "CNY");//符合ISO 4217标准的三位字母代码，默认人民币：CNY，详细列表请参见货币类型
////        if (orderShop.getOrderPrice().compareTo(new BigDecimal(1)) > 0)
//        map.add("refund_desc", refund_desc);//退款原因
////        map.add("notify_url", notify_url);//异步接收微信支付退款结果通知的回调地址，通知URL必须为外网可访问的url，不允许带参数如果参数中传了notify_url，则商户平台上配置的回调地址将不会生效。
////        map.add("sign", getSign(map));//通过签名算法计算得出的签名值，详见签名生成算法,本行务必放在最后
//
//        HttpHeaders headers = new HttpHeaders();
////        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//        headers.setContentType(MediaType.APPLICATION_XML);
//
//        //排序参数
//        TreeMap<String, String> treeMap = new TreeMap<>();
//        //把map转换成treemap成有序映射
//        for (int i = 0; i < map.size(); i++) {
//            String key = map.keySet().toArray()[i] + "";
//            if ("sign".equals(key)) {
//                continue;
//            }
//            treeMap.put(key, map.values().toArray()[i] + "");
//        }
//        List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(treeMap.entrySet());
//        //然后通过比较器来实现排序
//        Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
//            //升序排序
//            public int compare(Map.Entry<String, String> o1,
//                               Map.Entry<String, String> o2) {
//                return o1.getKey().compareTo(o2.getKey());
//            }
//        });
//
//        StringBuffer xmlString = new StringBuffer();
//        xmlString.append("<xml>");
//        for (int i = 0; i < treeMap.size(); i++) {
//            String key = treeMap.keySet().toArray()[i].toString();
//            String value = treeMap.values().toArray()[i].toString();
//
//            if ("sign".equals(key))
//                continue;
//
//            xmlString.append("<" + key + ">");
//            xmlString.append("<![CDATA");//CDATA标签用于说明数据不被XML解析器解析。
//            xmlString.append(value);
//            xmlString.append("]>");
//
//            xmlString.append("</" + key + ">");
//        }
//        //前面默认放在最后
//        xmlString.append("<sign>");
//        xmlString.append(getPrepareSign(map, APIKEY));
//        xmlString.append("</sign>");
//
//        xmlString.append("</xml>");
//
////        String str = xmlString.toString().replace("[", "").replace("]", "");
//        // 创建 HttpEntity
//        HttpEntity<String> requestEntity = new HttpEntity<>(xmlString.toString()
//                , headers);
//
//        String result = "";
//        try {
//            KeyStore ks = KeyStore.getInstance("PKCS12");//eg. PKCS12
//            ks.load(new FileInputStream(new File(certFilePath))
//                    , GlobalConstant.SHANGHUHAO.toCharArray());//密码就是商户号
//
//            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//            kmf.init(ks, GlobalConstant.SHANGHUHAO.toCharArray());//密码就是商户号
//
//            SSLContext ssl = SSLContext.getInstance("TLS");//eg. TLS
//            ssl.init(kmf.getKeyManagers(), null, null);
//
//            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ssl, NoopHostnameVerifier.INSTANCE);
//
//            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
//            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
//
//            restTemplate.setRequestFactory(factory);
//
//            result = restTemplate.postForObject(url, requestEntity, String.class);
//        } catch (Exception e) {
//            return null;
//        }
//        WechatOrderReturn wechatOrderReturn = (WechatOrderReturn) XmlUtils.convertXmlStrToObject(result, WechatOrderReturn.class);
//
//        return wechatOrderReturn;
//    }
//
//    /**
//     * 查询订单是否退款成功
//     *
//     * @param orderNum 平台的订单号
//     */
//    public static WechatOrderReturn isOrderRefundSuccess(RestTemplate restTemplate, String orderNum, Integer payOrigin) {
//        String url = "https://api.mch.weixin.qq.com/pay/refundquery";
//        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
//        if (payOrigin == 1) {
//            map.add("appid", MP_APPID);//MP_APPID
//        } else if (payOrigin == 2) {
//            map.add("appid", APP_APPID);//APP_APPID
//        }
//        map.add("mch_id", GlobalConstant.SHANGHUHAO);//商户号
//        map.add("nonce_str", UUID.randomUUID().toString().replace("-", ""));//随机字符串，长度要求在32位以内。
//        map.add("sign_type", "MD5");//签名类型，默认为MD5，支持HMAC-SHA256和MD5。
//        map.add("out_trade_no", orderNum);//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
////        map.add("offset", offset);//偏移量，当部分退款次数超过10次时可使用，表示返回的查询结果从这个偏移量开始取记录
////        map.add("sign", getSign(map));//通过签名算法计算得出的签名值，详见签名生成算法,本行务必放在最后
//
//        HttpHeaders headers = new HttpHeaders();
////        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//        headers.setContentType(MediaType.APPLICATION_XML);
//
//        //排序参数
//        TreeMap<String, String> treeMap = new TreeMap<>();
//        //把map转换成treemap成有序映射
//        for (int i = 0; i < map.size(); i++) {
//            String key = map.keySet().toArray()[i] + "";
//            if ("sign".equals(key)) {
//                continue;
//            }
//            treeMap.put(key, map.values().toArray()[i] + "");
//        }
//        List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(treeMap.entrySet());
//        //然后通过比较器来实现排序
//        Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
//            //升序排序
//            public int compare(Map.Entry<String, String> o1,
//                               Map.Entry<String, String> o2) {
//                return o1.getKey().compareTo(o2.getKey());
//            }
//        });
//
//        StringBuffer xmlString = new StringBuffer();
//        xmlString.append("<xml>");
//        for (int i = 0; i < treeMap.size(); i++) {
//            String key = treeMap.keySet().toArray()[i].toString();
//            String value = treeMap.values().toArray()[i].toString();
//
//            if ("sign".equals(key))
//                continue;
//
//            xmlString.append("<" + key + ">");
//            xmlString.append("<![CDATA");//CDATA标签用于说明数据不被XML解析器解析。
//            xmlString.append(value);
//            xmlString.append("]>");
//
//            xmlString.append("</" + key + ">");
//        }
//        //前面默认放在最后
//        xmlString.append("<sign>");
//        xmlString.append(getPrepareSign(map, APIKEY));
//        xmlString.append("</sign>");
//
//        xmlString.append("</xml>");
//
////        String str = xmlString.toString().replace("[", "").replace("]", "");
//        // 创建 HttpEntity
//        HttpEntity<String> requestEntity = new HttpEntity<>(xmlString.toString()
//                , headers);
//
//        String result = restTemplate.postForObject(url, requestEntity, String.class);
//
//        WechatOrderReturn wechatOrderReturn = (WechatOrderReturn) XmlUtils.convertXmlStrToObject(result, WechatOrderReturn.class);
//
//        return wechatOrderReturn;
//    }
//
//    /**
//     * 得到小程序的签名（小程序拿到参数后需要对参数单独进行签名,需要在服务器得到预订单后再用固定的参数进行一次签名）
//     */
//    public static OrderPrepare getXCSSign(OrderPrepare orderPrepare, String APIKEY) {
//        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
//        map.add("appId", orderPrepare.getAppid());//
//        map.add("timeStamp", TimeUtils.getLocalDatestamp());//
//        map.add("nonceStr", orderPrepare.getNonce_str());//
//        map.add("package", "prepay_id=" + orderPrepare.getPrepay_id());//
//        map.add("signType", orderPrepare.getSign_type());//
//        map.add("paySign", getPrepareSign(map, APIKEY));//通过签名算法计算得出的签名值，详见签名生成算法,本行务必放在最后
//
//        for (int i = 0; i < map.size(); i++) {
//
//        }
//        orderPrepare.setTimeStamp(map.get("timeStamp").toString().replace("[", "").replace("]", ""));
//        orderPrepare.setPackageStr(map.get("package").toString().replace("[", "").replace("]", ""));
//        orderPrepare.setPaySign(map.get("paySign").toString().replace("[", "").replace("]", ""));
//        return orderPrepare;
//    }
//
//    /**
//     * 得到APP的签名（APP拿到参数后需要对参数单独进行签名,需要在服务器得到预订单后再用固定的参数进行一次签名）
//     */
//    public static OrderPrepare getAPPSign(OrderPrepare wechatPrepare, String APIKEY) {
//
//
//        wechatPrepare.setTimeStamp(new BigDecimal(System.currentTimeMillis() * 0.001).longValue() + "");
//        wechatPrepare.setPaySign(WXAPPPayHelper.getAPPSign(wechatPrepare.getAppid(),
//                wechatPrepare.getPrepay_id(), wechatPrepare.getNonce_str(), wechatPrepare.getTimeStamp(), wechatPrepare.getMch_id(), APIKEY
//        ));
//        wechatPrepare.setPackageStr(wechatPrepare.getPackageValue());
//
//        return wechatPrepare;
//    }
//
//
//    /**
//     * 得到微信签名
//     * 第一步：对参数按照key=value的格式，并按照参数名ASCII字典序排序如下：
//     * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
//     * 第二步：拼接API密钥：
//     * stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注：key为商户平台设置的密钥key
//     * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注：MD5签名方式
//     * sign=hash_hmac("sha256",stringSignTemp,key).toUpperCase()="6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6" //注：HMAC-SHA256签名方式，部分语言的hmac方法生成结果二进制结果，需要调对应函数转化为十六进制字符串。
//     *
//     * @param map 微信参数列表
//     */
//    public static String getPrepareSign(MultiValueMap<String, Object> map, String APIKEY) {
//        TreeMap<String, Object> treeMap = new TreeMap<>();
//        //把map转换成treemap成有序映射
//        for (int i = 0; i < map.size(); i++) {
//            String key = map.keySet().toArray()[i] + "";
//            if ("sign".equals(key)) {
//                continue;
//            }
//            if ("paySign".equals(key)) {
//                continue;
//            }
//            treeMap.put(key, map.values().toArray()[i] + "");
//        }
//        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(treeMap.entrySet());
//        //然后通过比较器来实现排序
//        Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
//            //升序排序
//            public int compare(Map.Entry<String, Object> o1,
//                               Map.Entry<String, Object> o2) {
//                return o1.getKey().compareTo(o2.getKey());
//            }
//        });
//        String md5Str = "";
//        for (int i = 0; i < treeMap.size(); i++) {
//            if (i != 0) {
//                md5Str += "&";
//            }
//            md5Str += treeMap.keySet().toArray()[i] + "=" + treeMap.values().toArray()[i];
//        }
//        md5Str += "&key=" + APIKEY;
//        md5Str = md5Str.replace("[", "").replace("]", "");
//
//        String md5 = Md5Utils.MD5Encode(md5Str, true);
//        return md5;
//    }
//
//    // 构建service
//    private static Config config = null;
//    public static NativePayService nativePayService = null;
//    public static TransferBatchService transferBatchService = null;
//
//    private Config getConfig() {
//        if (config == null) {
//            // 初始化商户配置
//            config =
//                    new RSAAutoCertificateConfig.Builder()
//                            .merchantId(GlobalConstant.SHANGHUHAO)
//                            // 使用 com.wechat.pay.java.core.util
//                            // 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
//                            .privateKeyFromPath(wechatPrivateKeyPath)
//                            .merchantSerialNumber(GlobalConstant.XULIEHAO)
//                            .apiV3Key(APIKEY)
//                            .build();
//
//        }
//        return config;
//    }
//
//    /**
//     * 构件支付服务
//     */
//    private NativePayService getPayService() {
//        if (nativePayService == null) {
//            nativePayService = new NativePayService.Builder().config(getConfig()).build();
//        }
//        return nativePayService;
//    }
//
//    /**
//     * 构件转账服务
//     */
//    private TransferBatchService getTransferService() {
//        if (transferBatchService == null) {
//            // 初始化服务
//            transferBatchService = new TransferBatchService.Builder().config(getConfig()).build();
//        }
//        return transferBatchService;
//    }
//
//    /**
//     * native网页支付
//     *
//     * @param price 以分we点位
//     * @return codeUrl
//     */
//    public String payNative(int price, String title, String outTradeNo) {
//        // 使用自动更新平台证书的RSA配置
//        // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
//        NativePayService service = getPayService();
//
//        // request.setXxx(val)设置所需参数，具体参数可见Request定义
//        PrepayRequest request = new PrepayRequest();
//        Amount amount = new Amount();
//        amount.setTotal(price);
//        request.setAmount(amount);
//        request.setAppid(GlobalConstant.getWX_APPID(0));
//        request.setMchid(GlobalConstant.SHANGHUHAO);
//        request.setDescription(title);
//        request.setNotifyUrl("http://pts.luozisong.top:10000/expression/api/order/auth/wechatPayResult");
//        request.setOutTradeNo(outTradeNo);
//        // 调用下单方法，得到应答
//        PrepayResponse response = service.prepay(request);
//        // 使用微信扫描 code_url 对应的二维码，即可体验Native支付
////        System.out.println(response.getCodeUrl());
//
//        return response.getCodeUrl();
//    }
//
//    /**
//     * 查询订单状态，包括成功失败、退款成功等
//     */
//    public Transaction getOrderTransaction(OrderUser orderUser) throws Exception {
//        NativePayService service = getPayService();
//        QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
//        queryRequest.setMchid(GlobalConstant.SHANGHUHAO);
//        queryRequest.setOutTradeNo(orderUser.getOrderNum());
////        QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
////        queryRequest.setMchid(GlobalConstant.SHANGHUHAO);
////        queryRequest.setTransactionId(orderUser.getOrderNum());
//
//        try {
//            Transaction result = service.queryOrderByOutTradeNo(queryRequest);
//            return result;
//        } catch (ServiceException e) {
//            // API返回失败, 例如ORDER_NOT_EXISTS
//            System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
//            System.out.printf("reponse body=[%s]\n", e.getResponseBody());
//        }
//        return null;
//    }
//
//
//    /**
//     * 对用户进行批量转账,默认为一次就转账一笔
//     *
//     * @param appId        【商户appid】 申请商户号的appid或商户号绑定的appid（企业号corpid即为此appid）
//     * @param openId       【收款用户openid】 商户appid下，某用户的openid
//     * @param userName     用户真实姓名用于校验用的
//     * @param batchNo      【商家批次单号】 商户系统内部的商家批次单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
//     * @param batchName    【批次名称】 该笔批量转账的名称
//     * @param remark       【批次备注】 转账说明，UTF8编码，最多允许32个字符
//     * @param total_amount 【转账总金额】 转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致，否则无法发起转账操作
//     * @param total_num    【转账总笔数】 一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致，否则无法发起转账操作
//     */
//    public InitiateBatchTransferResponse batchTransfer(String appId, String openId, String userName, String batchNo, String batchName, String remark, Long total_amount, Integer total_num) {
//        if (TxtUtil.isEmpty(remark)) {
//            remark = batchName;
//        }
//        InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
//        request.setAppid(appId);
//        request.setOutBatchNo(batchNo);
//        request.setBatchName(batchName);
//        request.setBatchRemark(remark);
//        request.setTotalAmount(total_amount);
//        request.setTotalNum(total_num);
//
//        List<TransferDetailInput> transferDetailList = new ArrayList<>();
//        TransferDetailInput input = new TransferDetailInput();
//        input.setOpenid(openId);
//        input.setOutDetailNo(batchNo);
//        input.setTransferAmount(total_amount);
//        input.setTransferRemark(remark);
//        if (total_amount > 30) {//0.3元以上才支持实名校验
//            input.setUserName(userName);
//        }
//
//        transferDetailList.add(input);
//
//        request.setTransferDetailList(transferDetailList);
//        request.setTransferSceneId("1001");//默认为现金营销
//        TransferBatchService service = getTransferService();
//        InitiateBatchTransferResponse response = service.initiateBatchTransfer(request);
//        return response;
//    }
//
//}
